package com.starlinkdt.service.system.impl;

import com.starlinkdt.common.constant.HttpStatus;
import com.starlinkdt.common.domain.system.dto.OaiPermDto;
import com.starlinkdt.common.domain.system.entity.OaiAcc;
import com.starlinkdt.common.domain.system.entity.OaiPerm;
import com.starlinkdt.common.domain.system.entity.OaiServ;
import com.starlinkdt.common.enums.DisableStatus;
import com.starlinkdt.common.exception.ServiceException;
import com.starlinkdt.common.mapper.system.OaiAccMapper;
import com.starlinkdt.common.mapper.system.OaiPermMapper;
import com.starlinkdt.common.mapper.system.OaiServMapper;
import com.starlinkdt.common.utils.MyStringUtils;
import com.starlinkdt.common.utils.SecurityUtils;
import com.starlinkdt.service.system.IOaiPermService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * OAI权限Service业务层处理
 * 
 * @author system
 */
@Service
public class OaiPermServiceImpl implements IOaiPermService
{
    @Autowired
    private OaiPermMapper oaiPermMapper;

    @Autowired
    private OaiAccMapper oaiAccMapper;

    @Autowired
    private OaiServMapper oaiServMapper;

    private static final String permBizNoPre  = "UOP";

    private static final int permBizNoLength = 20;

    /**
     * 查询OAI权限列表
     *
     * @param oaiPermSearch OAI权限
     * @return OAI权限集合
     */
    @Override
    public List<OaiPerm> selectOaiPermList(OaiPerm oaiPermSearch) {
        List<OaiPerm> oaiPermList = oaiPermMapper.selectOaiPermList(oaiPermSearch);

        // 获取用户名称
        String[] accBizNos = oaiPermList.stream().map(OaiPerm::getAccBizNo).toArray(String[]::new);
        if (accBizNos.length > 0) {
            List<OaiAcc> oaiAccList = oaiAccMapper.selectOaiAccByAccBizNos(accBizNos);
            Map<String, String> oaiAccNameMap = oaiAccList.stream().collect(Collectors.toMap(OaiAcc::getAccBizNo, OaiAcc::getAccName));
            oaiPermList.forEach(v -> {
                v.setAccName(oaiAccNameMap.getOrDefault(v.getAccBizNo(), ""));
            });
        }

        // 获取服务名称
        String[] servBizNos = oaiPermList.stream().map(OaiPerm::getServBizNo).toArray(String[]::new);
        if (servBizNos.length > 0) {
            List<OaiServ> oaiServList = oaiServMapper.selectOaiServByServBizNos(servBizNos);
            Map<String, String> oaiServNameMap = oaiServList.stream().collect(Collectors.toMap(OaiServ::getServBizNo, OaiServ::getServName));
            oaiPermList.forEach(v -> {
                v.setServName(oaiServNameMap.getOrDefault(v.getServBizNo(), ""));
            });
        }

        return oaiPermList;
    }

    /**
     * 查询OAI权限
     *
     * @param permBizNo OAI权限唯一编码
     * @return OAI权限
     */
    @Override
    public OaiPerm selectOaiPermByPermBizNo(String permBizNo) {
        OaiPerm oaiPerm = oaiPermMapper.selectOaiPermByPermBizNo(permBizNo);
        if (oaiPerm == null) {
            throw new ServiceException("OAI权限不存在", HttpStatus.CONFLICT);
        }

        // 获取用户名称
        if (! oaiPerm.getAccBizNo().isEmpty()){
            OaiAcc oaiAcc = oaiAccMapper.selectOaiAccByAccBizNo(oaiPerm.getAccBizNo());
            oaiPerm.setAccName(oaiAcc.getAccName());
        }

        // 获取服务名称
        if (! oaiPerm.getServBizNo().isEmpty()) {
            OaiServ oaiServ = oaiServMapper.selectOaiServByServBizNo(oaiPerm.getServBizNo());
            oaiPerm.setServName(oaiServ.getServName());
        }

        return oaiPerm;
    }

    /**
     * 新增OAI权限
     *
     * @param oaiPermDto OAI权限
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = {Exception.class, Error.class})
    public int insertOaiPerm(OaiPermDto oaiPermDto) {
        // 检查OAI账户
        if (oaiPermDto.getAccBizNoList() == null || oaiPermDto.getAccBizNoList().isEmpty()) {
            throw new ServiceException("OAI账户不存在", HttpStatus.CONFLICT);
        }
        oaiPermDto.getAccBizNoList().forEach(v -> {
            if (oaiAccMapper.selectOaiAccByAccBizNo(v) == null) {
                throw new ServiceException("OAI账户不存在", HttpStatus.CONFLICT);
            }
        });

        // 检查OAI服务
        if (oaiPermDto.getServBizNoList() == null || oaiPermDto.getServBizNoList().isEmpty()) {
            throw new ServiceException("OAI服务不存在", HttpStatus.CONFLICT);
        }
        oaiPermDto.getServBizNoList().forEach(v -> {
            if (oaiServMapper.selectOaiServByServBizNo(v) == null) {
                throw new ServiceException("OAI服务不存在", HttpStatus.CONFLICT);
            }
        });

        // 添加OAI权限
        AtomicInteger resultNum = new AtomicInteger();
        oaiPermDto.getAccBizNoList().forEach(acc -> {
            oaiPermDto.getServBizNoList().forEach(serv -> {
                OaiPerm oaiPerm = oaiPermMapper.selectOaiPermByAccServ(acc, serv);
                if (oaiPerm == null) {
                    OaiPerm oaiPermInsert = getOaiPermEdit(oaiPermDto);
                    oaiPermInsert.setPermBizNo(MyStringUtils.genBizNo(permBizNoLength, permBizNoPre));
                    oaiPermInsert.setAccBizNo(acc);
                    oaiPermInsert.setServBizNo(serv);
                    oaiPermInsert.setCreateBy(SecurityUtils.getUsername());
                    resultNum.set(resultNum.get() + oaiPermMapper.insertOaiPerm(oaiPermInsert));
                } else {
                    OaiPerm oaiPermUpdate = getOaiPermEdit(oaiPermDto);
                    oaiPermUpdate.setPermBizNo(oaiPerm.getPermBizNo());
                    oaiPermUpdate.setUpdateBy(SecurityUtils.getUsername());
                    resultNum.set(resultNum.get() + oaiPermMapper.updateOaiPermByPermBizNo(oaiPermUpdate));
                }
            });
        });

        return resultNum.get();
    }

    /**
     * 修改OAI权限
     *
     * @param oaiPermDto OAI权限
     * @return 结果
     */
    @Override
    public int updateOaiPermByPermBizNo(OaiPermDto oaiPermDto) {
        // 检查OAI权限
        if (oaiPermDto.getPermBizNo() == null || oaiPermDto.getPermBizNo().isEmpty()) {
            throw new ServiceException("OAI权限不存在", HttpStatus.CONFLICT);
        }
        if (oaiPermMapper.selectOaiPermByPermBizNo(oaiPermDto.getPermBizNo()) == null) {
            throw new ServiceException("OAI权限不存在", HttpStatus.CONFLICT);
        }

        // 处理数据
        OaiPerm oaiPerm = getOaiPermEdit(oaiPermDto);
        oaiPerm.setPermBizNo(oaiPermDto.getPermBizNo());
        oaiPerm.setUpdateBy(SecurityUtils.getUsername());

        return oaiPermMapper.updateOaiPermByPermBizNo(oaiPerm);
    }

    private static OaiPerm getOaiPermEdit(OaiPermDto oaiPermDto) {
        OaiPerm oaiPerm = new OaiPerm();
        oaiPerm.setEffectiveStart(oaiPermDto.getEffectiveStart());
        oaiPerm.setEffectiveEnd(oaiPermDto.getEffectiveEnd());
        return oaiPerm;
    }

    /**
     * 启用OAI权限
     *
     * @param permBizNos OAI权限唯一编码
     * @return 结果
     */
    @Override
    public int enableOaiPermByPermBizNos(String[] permBizNos) {
        return oaiPermMapper.updateOaiPermStatusByPermBizNos(permBizNos, DisableStatus.ENABLE.getType(), SecurityUtils.getUsername());
    }

    /**
     * 禁用OAI权限
     *
     * @param permBizNos OAI权限唯一编码
     * @return 结果
     */
    @Override
    public int disableOaiPermByPermBizNos(String[] permBizNos) {
        return oaiPermMapper.updateOaiPermStatusByPermBizNos(permBizNos, DisableStatus.DISABLE.getType(), SecurityUtils.getUsername());
    }

    /**
     * 删除OAI权限
     *
     * @param permBizNo OAI权限唯一编码
     * @return 结果
     */
    @Override
    public int deleteOaiPermByPermBizNo(String permBizNo) {
        if (oaiPermMapper.selectOaiPermByPermBizNo(permBizNo) == null) {
            throw new ServiceException("OAI权限不存在", HttpStatus.CONFLICT);
        }

        return oaiPermMapper.deleteOaiPermByPermBizNo(permBizNo, SecurityUtils.getUsername());
    }

    /**
     * 批量删除OAI权限
     *
     * @param permBizNos OAI权限唯一编码
     * @return 结果
     */
    @Override
    public int deleteOaiPermByPermBizNos(String[] permBizNos) {
        return oaiPermMapper.deleteOaiPermByPermBizNos(permBizNos, SecurityUtils.getUsername());
    }

}
